package com.cqupt.sendMes.service.Impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.cqupt.sendMes.dao.BandTaskDao;
import com.cqupt.sendMes.dao.TaskDao;
import com.cqupt.sendMes.dao.UserDao;
import com.cqupt.sendMes.dto.TaskDTO;
import com.cqupt.sendMes.dto.TaskQueryDTO;
import com.cqupt.sendMes.entity.BandTask;
import com.cqupt.sendMes.entity.Task;
import com.cqupt.sendMes.entity.User;
import com.cqupt.sendMes.enums.HttpStatusEnum;
import com.cqupt.sendMes.enums.StatusEnum;
import com.cqupt.sendMes.enums.TaskActivateEnum;
import com.cqupt.sendMes.enums.TaskQueryType;
import com.cqupt.sendMes.exception.BusinessException;
import com.cqupt.sendMes.service.TaskService;
import com.cqupt.sendMes.utils.*;
import com.cqupt.sendMes.vo.UserInfoVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalTime;
import java.time.MonthDay;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


@Service
@Slf4j
public class TaskServiceImpl implements TaskService {
    @Autowired
    private UserDao userDao;
    @Autowired
    private EncryptUtils encryptUtils;

    @Autowired
    private TaskDao taskDao;

    @Autowired
    private BandTaskDao bandTaskDao;
    @Autowired
    WxPush wxPush;
    @Override
    public List<Result> sendMes(Message message) {
        //拿到对应的人
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getStatus, StatusEnum.NO_DELETED.getCode());
        List<User> userList = userDao.selectList(lambdaQueryWrapper);
        List<Result> results = new ArrayList<>();

        for (User user : userList) {
            log.info("发送的用户ID{}", user.getUserUid());
            String uid = encryptUtils.decryptAES(user.getUserUid());
            if(StrUtil.isBlank(uid)){
                continue;
            }
            message.setUid(uid);
            results.add(wxPush.send(message));
        }
        log.info("发送结果{}", results);
        return results;
    }

    @Override
    public Boolean addTask(TaskDTO taskDTO) {
        LambdaQueryWrapper<Task> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Task::getTaskName, taskDTO.getTaskName())
                .eq(Task::getStatus, StatusEnum.NO_DELETED.getCode());
        if(taskDao.selectOne(lambdaQueryWrapper)!=null){
            log.warn("添加失败，任务名称重复");
            throw new BusinessException(HttpStatusEnum.OBJECT_EXIST.getCode(), "任务名"+HttpStatusEnum.OBJECT_EXIST.getMessage());
        }
        //查询当前用户
        UserInfoVO userInfo = UserHelper.getCurrentUser();

        //构造对象记录
        Task task = new Task();
        BeanUtils.copyProperties(taskDTO, task);
        task.setStatus(StatusEnum.NO_DELETED.getCode());
        task.setTaskStatus(TaskActivateEnum.ACTIVE.getCode());
        if (userInfo != null) {
            task.setTaskUserId(userInfo.getId());
            task.setTaskUsername(userInfo.getUsername());
        }

        taskDao.insert(task);
        log.info("任务添加成功");
        return true;
    }

    @Override
    public PageResult<Task> queryTask(TaskQueryDTO taskQueryDTO) {
        //构造查询wrapper
        LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<>();
        //当前用户是否是管理员
        UserInfoVO userInfo = UserHelper.getCurrentUser();
        if (userInfo != null && userInfo.getRoleId() != 1) {
            log.info("此用户是普通用户");
            queryWrapper.eq(Task::getTaskUserId, userInfo.getId());
        }
        queryWrapper.eq(ObjectUtil.isNotNull(taskQueryDTO.getId()), Task::getId, taskQueryDTO.getId())
                .like(StrUtil.isNotBlank(taskQueryDTO.getTaskName()), Task::getTaskName, taskQueryDTO.getTaskName())
                .eq(ObjectUtil.isNotNull(taskQueryDTO.getTaskType()), Task::getTaskType, taskQueryDTO.getTaskType())
                .eq(ObjectUtil.isNotNull(taskQueryDTO.getTaskStatus()), Task::getTaskStatus, taskQueryDTO.getTaskStatus())
                .like(StrUtil.isNotBlank(taskQueryDTO.getTaskUsername()), Task::getTaskUserId, taskQueryDTO.getTaskUsername())
                .eq(ObjectUtil.isNotNull(taskQueryDTO.getExecutionDate()), Task::getExecutionDate, taskQueryDTO.getExecutionDate())
                .eq(ObjectUtil.isNotNull(taskQueryDTO.getExecutionTime()), Task::getExecutionTime, taskQueryDTO.getExecutionTime())
                .eq(Task::getStatus, StatusEnum.NO_DELETED.getCode());
        List<Task> tasks;
        //1.设置·分页参数
        PageHelper.startPage(taskQueryDTO.getCurrentPage(),taskQueryDTO.getPageSize());
        //2.执行查询
        List<Task> taskList = taskDao.selectList(queryWrapper);
        //判断查询类型
        if(taskQueryDTO.getQueryType().equals(TaskQueryType.MY_BAND.getType())){
            //查询此用户绑定的任务
            List<BandTask> bandTasks = getBandTasks();
            //执行封装
            tasks= taskList.stream().filter(task -> bandTasks.stream().anyMatch(bandTask -> bandTask.getTaskId().equals(task.getId()))).collect(Collectors.toList());
        } else {
            //查询创建的任务
            tasks = taskList;
        }

        //3.执行封装
        PageInfo<Task> pageInfo = new PageInfo<>(tasks);

        log.info("查询成功，{}", pageInfo.getList());
        return PageResult.build(pageInfo.getPageNum(), pageInfo.getTotal(), pageInfo.getPageSize(), pageInfo.getList());
    }

    @Override
    public Boolean deleteTask(Integer id) {
        Task task = getTaskById(id);
        validateTask(task);
        //查询当前用户
        validatedAuth(task);
        LambdaQueryWrapper<BandTask> queryBandTask = new LambdaQueryWrapper<>();
        queryBandTask.eq(BandTask::getTaskId, id).eq(BandTask::getStatus, StatusEnum.NO_DELETED.getCode());
        List<BandTask> bandTasks = bandTaskDao.selectList(queryBandTask);
        if (!bandTasks.isEmpty()) {
            log.info("任务存在绑定，无法删除");
            throw new BusinessException("任务存在绑定，无法删除");
        }
        UpdateWrapper<Task> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id)
                .set("status", StatusEnum.DELETED.getCode());
        taskDao.update(null, updateWrapper);
        log.info("删除任务成功");
        return true;
    }
    @Override
    public Boolean updateTask(TaskDTO taskDTO) {
        Task task = getTaskById(taskDTO.getId());
        validateTask(task);
        //查询当前用户

        //如果当前用户不是管理员
        validatedAuth(task);

        UpdateWrapper<Task> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", taskDTO.getId());
        if(StrUtil.isNotBlank(taskDTO.getTaskName())){
            updateWrapper.set("task_name", taskDTO.getTaskName());
        }
        if(StrUtil.isNotBlank(taskDTO.getTaskContent())){
            updateWrapper.set("task_content", taskDTO.getTaskContent());
        }
        if(ObjectUtil.isNotNull(taskDTO.getExecutionDate())){
            updateWrapper.set("execution_date", taskDTO.getExecutionDate());
        }
        if(ObjectUtil.isNotNull(taskDTO.getExecutionTime())){
            updateWrapper.set("execution_time", taskDTO.getExecutionTime());
        }
        taskDao.update(null, updateWrapper);
        log.info("更新任务成功");
        return true;
    }

    @Override
    public Boolean changeStatus(Integer taskId, String status) {
        Task task = getTaskById(taskId);
        //检查任务是否存在
        validateTask(task);

        //如果当前用户不是管理员
        validatedAuth(task);

        UpdateWrapper<Task> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", taskId)
                .set("task_status", status);
        taskDao.update(null, updateWrapper);
        return true;
    }

    @Override
    public Boolean bandTask(Integer taskId) {
        Task task = getTaskById(taskId);
        //查询任务是否存在
        validateTask(task);
        //查询当前用户
        validatedAuth(task);

        UserInfoVO userInfo = UserHelper.getCurrentUser();
        if (ObjectUtil.isNull(userInfo)) {
            log.warn("操作失败，读取用户失败");
            throw new BusinessException(HttpStatusEnum.OBJECT_NOT_EXIST.getCode(), HttpStatusEnum.OBJECT_NOT_EXIST.getMessage());
        }
        //执行绑定任务
        BandTask bandTask = BandTask.builder().taskId(taskId)
                .taskName(task.getTaskName())
                .userId(userInfo.getId())
                .username(userInfo.getUsername())
                .status(StatusEnum.NO_DELETED.getCode())
                .build();
        bandTaskDao.insert(bandTask);
        return true;
    }

    @Override
    public List<BandTask> getBandTasks(){
        /**
         * 获取用户订阅的所有任务
         * */
        UserInfoVO userInfo = UserHelper.getCurrentUser();
        LambdaQueryWrapper<BandTask> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BandTask::getStatus, StatusEnum.NO_DELETED.getCode())
                .eq(BandTask::getUserId, userInfo.getId());
        List<BandTask> bandTaskList = bandTaskDao.selectList(lambdaQueryWrapper);
        if (ObjectUtil.isNull(bandTaskList)) {
            log.warn("操作失败，该用户没有绑定任务");
//            throw new BusinessException(HttpStatusEnum.OBJECT_NOT_EXIST.getCode(), HttpStatusEnum.OBJECT_NOT_EXIST.getMessage());
        }
        log.info("查询到绑定任务列表{}", bandTaskList);
        return bandTaskList;
    }
    @Override
    public BandTask getBandTaskById(Integer taskId){
        /**
         * 获取用户订阅的单个任务
         * */
        UserInfoVO userInfo = UserHelper.getCurrentUser();
        LambdaQueryWrapper<BandTask> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BandTask::getTaskId, taskId)
                .eq(BandTask::getStatus, StatusEnum.NO_DELETED.getCode())
                .eq(BandTask::getUserId, userInfo.getId());
        BandTask bandTask = bandTaskDao.selectOne(lambdaQueryWrapper);
        if (ObjectUtil.isNull(bandTask)) {
            log.warn("操作失败，未查询到对应的任务");
            throw new BusinessException(HttpStatusEnum.OBJECT_NOT_EXIST.getCode(), HttpStatusEnum.OBJECT_NOT_EXIST.getMessage());
        }
        log.info("查询到绑定任务{}", bandTask);
        return bandTask;
    }



    @Override
    public Boolean unBandTask(Integer taskId) {
        UserInfoVO userInfo = UserHelper.getCurrentUser();
        //查询绑定关系是否存在
        getBandTaskById(taskId);
        //执行解绑任务
        UpdateWrapper<BandTask> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("task_id", taskId)
                .eq("user_id", userInfo.getId())
                .set("status", StatusEnum.DELETED.getCode());
        bandTaskDao.update(null, updateWrapper);
        return true;
    }

    @Override
    public Task getTaskById(Integer taskId) {
        LambdaQueryWrapper<Task> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Task::getId, taskId)
                .eq(Task::getStatus, StatusEnum.NO_DELETED.getCode());
        return taskDao.selectOne(lambdaQueryWrapper);
    }

    @Override
    public List<Task> getTaskList() {
        MonthDay today = MonthDay.now();
        LocalTime now = LocalTime.now(); // 获取当前时间，只统计比当前时间更晚的
        LambdaQueryWrapper<Task> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Task::getStatus, StatusEnum.NO_DELETED.getCode())
                .eq(Task::getTaskStatus, TaskActivateEnum.ACTIVE.getCode())
                .ge(Task::getExecutionTime, now);
        List<Task> taskList = taskDao.selectList(lambdaQueryWrapper);
        // 去除指定日期的任务
        return taskList.stream().filter(task -> (task.getExecutionDate() == null || MonthDay.from(task.getExecutionDate()).equals(today))).collect(Collectors.toList());
    }


    @Override
    public void validateTask(Task task) {
        if(ObjectUtil.isNull(task)){
            log.warn("操作失败，任务不存在");
            throw new BusinessException(HttpStatusEnum.OBJECT_NOT_EXIST.getCode(), HttpStatusEnum.OBJECT_NOT_EXIST.getMessage());
        }
    }

    @Override
    public void validatedAuth(Task task) {
        UserInfoVO userInfo = UserHelper.getCurrentUser();
        log.info("当前用户信息：{}", userInfo);
        if (userInfo != null && userInfo.getRoleId() != 1) {
            //TODO:判断当前用户是不是超管，后续可以优化下
            if (!Objects.equals(task.getTaskUserId(), userInfo.getId())) {
                log.warn("操作失败，不是任务创建者");
                throw new BusinessException(HttpStatusEnum.NO_AUTHORITY.getCode(), HttpStatusEnum.NO_AUTHORITY.getMessage());
            }
        }

    }
}
